#pragma once
#include"Operator.h"

template<class T>
class Calculator
{
private:
	stack<double> m_num;
	stack<unique_ptr<Operator>>m_opr;
	void calculate()
	{
		double a[2] = { 0 };
		for (auto i = 0; i < m_opr.top()->numOperator(); i++)
		{
			a[i] = m_num.top();
			m_num.pop();
		}
		m_num.push(m_opr.top()->get(a[1][0]));
		m_opr.pop();
	}


public:
	Calculator()
	{
		m_opr.push(make_unique<Hash>());
	}
	double doIt(const string& exp)
	{
		for (auto it = exp.begin(); it != exp.end();)
		{
			if (isNum(it))
				m_num.push(readNum(it));
			else
			{
				char o = *it++;
				unique_ptr <Operator> oo;
				if (o == '+')
					oo = make_unique<Plus>();
				else if (o == '-')
					oo = make_unique<Minus>();
				else if (o == '*')
					oo = make_unique<Multiply>();
				else if (o == '/')
					oo = make_unique<Divide>();
				else if (o == '=')
					oo = make_unique < Equal> ();
				while (oo->precedence() <= m_opr.top()->precedence())
				{
					if (m_opr.top()->symbol() == '#')
						break;
					calculate();
				}
				if (oo->symbol() != '=')
					m_opr.push(std::move(oo));
			}
		}
		double result = m_num.top();
		m_num.pop();
		return result;
	}
};